package app.netant.book.base;

import cn.lily.com.db.DBFactory;
import cn.lily.com.db.container.reader.DataTable;
import cn.lily.com.db.sql.DBManager;
import cn.lily.com.db.sql.manager.DBOfflineManager;
import cn.lily.com.enviroment.Enviroment;
import cn.lily.com.lang.number.MathUtil;

public abstract class BaseRoot {
	
	protected String pageUrl = "https://www.dztxt.com/1_";
	
	protected String homeUrl = "https://www.dztxt.com/1_1/";
	
	protected String tableKey = "";
	protected String baseType = null;
	
	public void analyse(int maxIdx){
		
		resume();
		
		System.out.println("整体处理开始........");
		
		for(int i=1;i<=maxIdx;i++){
			
			String url = "";
			
			url = this.buildUrl(i);
			
			System.out.println("第"+i+"页数据开始处理！");
			
			BasePage page = null;
			
			try {
				page = this.buildPage(url);
				page.setBaseType(this.baseType);
				
				page.analyse();
				
			} catch (Exception e) {
				e.printStackTrace();
				getDBManager().executeUpdate("insert into ${schema}.NET_"+this.tableKey.trim().toUpperCase()+"_EXCEP (EXCEP_ID,EXCEP_URL,EXCEP_LEVEL) "
						+ "values ('"+System.currentTimeMillis()+""+MathUtil.random(3)+"','"+url+"','1') ");	
				continue;
			} finally {
				if(page != null){
					page.free();
				}
			}
			
		}
		
		System.out.println("整体处理结束........");
		
	}
	
	public void analyse(int minIdx,int maxIdx){
		
		System.out.println("整体处理开始........");
		
		for(int i=minIdx;i<=maxIdx;i++){
			
			String url = "";
			
			url = this.buildUrl(i);
			
			System.out.println("第"+i+"页数据开始处理！");
			
			BasePage page = null;
			
			try {
				page = this.buildPage(url);
				page.setBaseType(this.baseType);
				
				page.analyse();
				
			} catch (Exception e) {
				e.printStackTrace();
				getDBManager().executeUpdate("insert into ${schema}.NET_"+this.tableKey.trim().toUpperCase()+"_EXCEP (EXCEP_ID,EXCEP_URL,EXCEP_LEVEL) "
						+ "values ('"+System.currentTimeMillis()+""+MathUtil.random(3)+"','"+url+"','1') ");	
				continue;
			}  finally {
				if(page != null){
					page.free();
				}
			}
			
		}
		
		System.out.println("整体处理结束........");
		
	}
	
	public void excep(int i){
		
		System.out.println("异常处理开始........");
		
		getDBManager().executeUpdate("delete from ${schema}.NET_"+this.tableKey.trim().toUpperCase()+"_INFO "
				+ "where NOVEL_URL in "
				+ "(select EXCEP_URL from ${schema}.NET_"+this.tableKey.trim().toUpperCase()+"_EXCEP)");
		
		DataTable exptable = getDBManager().executeQueryTable("select * from ${schema}.NET_"+this.tableKey.trim().toUpperCase()+"_EXCEP");
		
		while(exptable.next()){
			
			Enviroment.getEnv().getLogBean().beginLog();
			
			System.out.println("第"+i+"次循环异常处理中................");
			try {
				
				String level = exptable.getString("EXCEP_LEVEL");
				String href = exptable.getString("EXCEP_URL");
				
				
				System.out.println("异常地址开始处理："+href);
				
				if("1".equals(level)){
					
					BasePage page = this.buildPage(href);
					page.setBaseType(this.baseType);
					
					page.analyse();
					
					page.free();
					
				}else if("2".equals(level)){
					
					DataTable dataTable = getDBManager().executeQueryTable("select * from ${schema}.NET_"+this.tableKey.trim().toUpperCase()+"_INFO where NOVEL_URL='"+href+"'");
					if(dataTable.next()){
						continue;
					}
					
					BaseEntity entity = this.buildEntity();
					entity.setNovelUrl(href);
					
					if(this.baseType != null && !"".equals(this.baseType)){
						entity.setNovelType(this.baseType);
					}
					
					this.afterEntity(entity);
					
					BaseDetail detail = this.buildDetail(href);		
					detail.setEntity(entity);
					
					detail.analyse();
					
					detail.free();
					
				}
				
				getDBManager().executeUpdate("delete from ${schema}.NET_"+this.tableKey.trim().toUpperCase()+"_EXCEP where EXCEP_ID='"+exptable.getString("EXCEP_ID")+"'");
				
			} catch (Exception e) {
				e.printStackTrace();
				continue;
			}
			
			Enviroment.getEnv().getLogBean().endLog();
		}
		
		System.out.println("异常处理结束........");

	}
	
	public abstract void afterEntity(BaseEntity entity);

	/**
	 * 循环异常处理
	 */
	public void excepCycle(){
		
		System.out.println("循环异常处理开始...........");
		
		int i=0;
		while(true){
			
			System.out.println("第"+i+"次循环处理开始...........");
			
			excep(i);
			
			System.out.println("第"+i+"次循环处理结束...........");
			i++;
			
			DataTable excepTable = DBFactory.getThreadDB().executeQueryTable("select EXCEP_URL from ${schema}.NET_"+this.tableKey.trim().toUpperCase()+"_EXCEP");
			if(excepTable.getRecordCount() == 0){
				break;
			}
			
		}
		
	}
	
	public DBManager getDBManager(){
		return DBOfflineManager.getDBManager();
	}
	
	/**
	 * 断点续传
	 */
	public void resume(){
		
		System.out.println("断点续传处理开始........");
		
		getDBManager().executeUpdate("delete from ${schema}.NET_"+this.tableKey.trim().toUpperCase()+"_INFO "
				+ "where NOVEL_URL in "
				+ "(select EXCEP_URL from ${schema}.NET_"+this.tableKey.trim().toUpperCase()+"_EXCEP)");
		
		getDBManager().executeUpdate("delete from ${schema}.NET_"+this.tableKey.trim().toUpperCase()+"_EXCEP");
		
		System.out.println("断点续传处理结束........");
		
	}
	
	public void setPageUrl(String pageUrl) {
		this.pageUrl = pageUrl;
	}

	public void setHomeUrl(String homeUrl) {
		this.homeUrl = homeUrl;
	}

	public void setTableKey(String tableKey) {
		this.tableKey = tableKey;
	}
	
	public void setBaseType(String baseType) {
		this.baseType = baseType;
	}

	public abstract String buildUrl(int pageIdx);
	public abstract BasePage buildPage(String url);
	public abstract BaseDetail buildDetail(String url);
	public abstract BaseEntity buildEntity();
	
}
